﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Authorization;
using NSubstitute.Extensions;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Modularity;
using Volo.Abp.Security.Claims;

namespace FlyingEye.WebTests
{
    [DependsOn(
        typeof(AbpAspNetCoreTestBaseModule),
        typeof(AbpAspNetCoreMvcModule),
        typeof(DeviceOpsServiceModule)
    )]
    public class WebTestModule : AbpModule
    {
        public override Task PreConfigureServicesAsync(ServiceConfigurationContext context)
        {
            // 正确加载项目中的配置文件
            var currentDir = Path.GetDirectoryName(this.GetType().Assembly.Location) ?? throw new InvalidOperationException("程序集路基错误。");
            var baseDir = Path.Combine(currentDir, "../../../../", "FlyingEye.DeviceOpsService");

            var builder = new ConfigurationBuilder()
           .SetBasePath(baseDir);

            context.Services.ReplaceConfiguration(builder.Build());

            return base.PreConfigureServicesAsync(context);
        }

        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            // 关闭所有认证检查，仅在集成测试环境中使用
            context.Services.Configure<AuthorizationOptions>(options =>
            {
                options.DefaultPolicy = new AuthorizationPolicyBuilder().RequireAssertion(_ => true).Build();
            });

            context.Services.PreConfigure<IMvcBuilder>(builder =>
            {
                builder.PartManager.ApplicationParts.Add(new CompiledRazorAssemblyPart(typeof(DeviceOpsServiceModule).Assembly));
            });
        }
   
        public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();

            // 伪造认证信息
            app.Use(async (ctx, next) =>
            {
                // 获取 FakeCurrentPrincipalAccessor 的认证信息，同步到 HTTP 上下文
                var principalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
                ctx.User = principalAccessor.Principal;  // 将线程主体同步到HttpContext
                await next();
            });

            base.OnPreApplicationInitialization(context);
        }
    }
}
